/**
 * 消息验证工具
 * 提供消息格式验证和内容过滤功能
 */

const config = require('./config');

class MessageValidator {
  constructor() {
    this.messageTypes = [
      'join',
      'leave', 
      'message',
      'private',
      'broadcast',
      'ping',
      'pong',
      'status',
      'error'
    ];
  }

  /**
   * 验证消息格式
   */
  validateFormat(message) {
    if (!message || typeof message !== 'object') {
      return { valid: false, error: '消息必须是对象格式' };
    }

    const { type, content, from, to, messageId, timestamp } = message;

    // 验证必需字段
    if (!type) {
      return { valid: false, error: '消息类型不能为空' };
    }

    if (!this.messageTypes.includes(type)) {
      return { valid: false, error: `无效的消息类型: ${type}` };
    }

    // 验证内容长度
    if (content && typeof content === 'string') {
      const maxLength = config.get('message.maxLength', 1000);
      if (content.length > maxLength) {
        return { valid: false, error: `消息内容超出长度限制 (${maxLength} 字符)` };
      }
    }

    // 验证发送者
    if (from && typeof from !== 'string') {
      return { valid: false, error: '发送者ID必须是字符串' };
    }

    // 验证接收者 (私聊消息)
    if (type === 'private' && !to) {
      return { valid: false, error: '私聊消息必须指定接收者' };
    }

    return { valid: true };
  }

  /**
   * 过滤消息内容
   */
  filterContent(content) {
    if (typeof content !== 'string') {
      return content;
    }

    // 基本的HTML标签过滤
    let filtered = content
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#x27;')
      .replace(/\//g, '&#x2F;');

    // 过滤潜在的脚本内容
    filtered = filtered.replace(/javascript:/gi, '');
    filtered = filtered.replace(/on\w+=/gi, '');

    return filtered.trim();
  }

  /**
   * 验证用户昵称
   */
  validateNickname(nickname) {
    if (!nickname || typeof nickname !== 'string') {
      return { valid: false, error: '昵称不能为空' };
    }

    const maxLength = config.get('security.maxNicknameLength', 20);
    if (nickname.length > maxLength) {
      return { valid: false, error: `昵称长度不能超过 ${maxLength} 字符` };
    }

    // 检查是否包含特殊字符
    const allowedPattern = /^[a-zA-Z0-9\u4e00-\u9fa5_-]+$/;
    if (!allowedPattern.test(nickname)) {
      return { valid: false, error: '昵称只能包含字母、数字、中文、下划线和横线' };
    }

    // 检查敏感词 (简单示例)
    const forbiddenWords = ['admin', 'root', 'system', '管理员'];
    const lowerNickname = nickname.toLowerCase();
    for (const word of forbiddenWords) {
      if (lowerNickname.includes(word.toLowerCase())) {
        return { valid: false, error: '昵称包含敏感词汇' };
      }
    }

    return { valid: true };
  }

  /**
   * 创建标准消息格式
   */
  createMessage(type, content, from = null, to = null, extra = {}) {
    const message = {
      type,
      content: this.filterContent(content),
      from,
      to,
      messageId: this.generateMessageId(),
      timestamp: new Date().toISOString(),
      ...extra
    };

    return message;
  }

  /**
   * 生成消息ID
   */
  generateMessageId() {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }

  /**
   * 验证速率限制
   */
  checkRateLimit(clientId, rateLimitMap) {
    const now = Date.now();
    const rateLimit = config.get('message.rateLimit', 10);
    const windowMs = 1000; // 1秒窗口

    if (!rateLimitMap.has(clientId)) {
      rateLimitMap.set(clientId, []);
    }

    const clientRequests = rateLimitMap.get(clientId);
    
    // 清理过期的请求记录
    const validRequests = clientRequests.filter(timestamp => now - timestamp < windowMs);
    
    // 检查是否超过限制
    if (validRequests.length >= rateLimit) {
      return { allowed: false, error: '消息发送过于频繁，请稍后再试' };
    }

    // 记录当前请求
    validRequests.push(now);
    rateLimitMap.set(clientId, validRequests);

    return { allowed: true };
  }
}

module.exports = MessageValidator;